/************************************************/
/*    Auteur    : Yoann NICOD                   */
/*    Programme : Atomic Bomberman Origins      */
/*    Fichier   : moduleaudio.cpp               */
/*    Date      : 18/11/2012                    */
/************************************************/

#include "moduleaudio.h"
#include "debug.h"
#include "general.h"
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <dos.h>

map<UINT_PTR, Sound*> ModuleAudio::m_ListeSonsJoues;

FichierSon::FichierSon()
{
	m_TypeSon = AucunType;
	*m_NomFichier = 0;
}

FichierSon::~FichierSon()
{
}

ModuleAudio::ModuleAudio()
{
	Log("Chargement des fichiers audio...", 1);
	ChargerFichiersSon();
}

ModuleAudio::~ModuleAudio()
{
}

void ModuleAudio::ArreterSon(int IDSon)
{
	Sound* pSon = (Sound *)IDSon;

//	cout << "Arret du son " << IDSon << endl;
	
	pSon->Stop();
	delete pSon;

	return;
}

int ModuleAudio::JouerSon(int TypeSon, bool JouerEnBoucle, bool SuppressionAutomatique)
{
	char *pNomFichier = NULL;
	FichierSon *pFichierSon;

	pFichierSon = ChoisirSon(TypeSon);
	if(pFichierSon == NULL)
	{
		char Buf[64] = {0};
		sprintf(Buf, "Aucun fichier son existant pour le type %d", TypeSon);
		Log(Buf, 2);
		return 0;
	}

	Sound *pSon = new Sound();

	if(pSon == NULL)
	{
		Log("Impossible d'allouer la memoire pour le nouveau son", 2);
		return NULL;
	}

//	cout << "Lancement du son..." << endl;
	
	pSon->SetLoop(JouerEnBoucle);
	pSon->SetBuffer(pFichierSon->m_Buffer);
	pSon->Play();

	if(!JouerEnBoucle && SuppressionAutomatique)
	{
		UINT_PTR IDTimer = SetTimer(NULL, 0, (UINT)(pFichierSon->m_Buffer.GetDuration()*1000), ModuleAudio::CallbackSuppressionSon);
		m_ListeSonsJoues.insert(pair<UINT_PTR, Sound*>(IDTimer, pSon));
	}

	return (int)pSon;
}

VOID CALLBACK ModuleAudio::CallbackSuppressionSon(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
	KillTimer(hwnd, idEvent);

	map<UINT_PTR, Sound*>::iterator it;

	it = m_ListeSonsJoues.find((UINT_PTR)idEvent);

	if(it != m_ListeSonsJoues.end())
	{
		Sound *pSon = it->second;

		ArreterSon((int)pSon);
		m_ListeSonsJoues.erase(it);
	}
	else
		Log("Tentative de suppression d'un son non existant", 1);
	
	return;
}

void ModuleAudio::ChargerFichiersSon()
{
	HANDLE hFichier;
	WIN32_FIND_DATA FichierInfo;
	char Patron[MAX_PATH];
	FichierSon FichierSonTemporaire;

	sprintf(Patron, "%s*.wav", CHEMIN_SONS);
	hFichier = FindFirstFile(Patron, &FichierInfo);
	
	if(hFichier == INVALID_HANDLE_VALUE)
	{
		Log("\t(WARNING) Aucuns fichiers son", 1);
		return;
	}

	char Buf[64] = {0};
	sprintf(Buf, "\t%s", FichierInfo.cFileName);
	Log(Buf, 1);
	
	strncpy(FichierSonTemporaire.m_NomFichier, FichierInfo.cFileName, 255);
	AjouterFichierSon(FichierSonTemporaire);

	int i = 0; ////////////////
	while(FindNextFile(hFichier,&FichierInfo)) 
	{
		++i;/////
		if(i > 10) break; //////

		sprintf(Buf, "\t%s", FichierInfo.cFileName);
		Log(Buf, 1);

		strncpy(FichierSonTemporaire.m_NomFichier, FichierInfo.cFileName, 255);
		AjouterFichierSon(FichierSonTemporaire);
	}
 
	FindClose(hFichier);
}

int ModuleAudio::AjouterFichierSon(FichierSon &MonFichierSon)
{
	map<int, vector<FichierSon>>::iterator it;

	char CheminComplet[MAX_PATH] = {0};
	sprintf(CheminComplet, "%s%s", CHEMIN_SONS, MonFichierSon.m_NomFichier);

	if (!MonFichierSon.m_Buffer.LoadFromFile(CheminComplet))
	{
		char Buf[64] = {0};
		sprintf(Buf, "Erreur lors de l'ouverture du fichier %s", MonFichierSon.m_NomFichier);
		Log(Buf, 1);

		return 0;
	}

	it = m_ListeFichiersSon.find(MonFichierSon.m_TypeSon);
	if(it != m_ListeFichiersSon.end())
		it->second.push_back(MonFichierSon);
	else
	{
		vector<FichierSon> Vect;
		Vect.push_back(MonFichierSon);
		m_ListeFichiersSon.insert(std::pair<int, vector<FichierSon>>(MonFichierSon.m_TypeSon, Vect));
	}

	return 1;
}

FichierSon *ModuleAudio::ChoisirSon(int TypeSon)
{
	int NombreFichiersCorrespondants = 0;
	map<int, vector<FichierSon>>::iterator it;

	it = m_ListeFichiersSon.find(TypeSon);

	if(it == m_ListeFichiersSon.end())
		return NULL;
	else
	{
		NombreFichiersCorrespondants = it->second.size();
		int Index = Randomizer::Random(0, NombreFichiersCorrespondants - 1);
		return &it->second[Index];
	}
}